home *** CD-ROM | disk | FTP | other *** search
- #include "flame.h"
-
- #define maxColors 256
-
- short Rand(short max);
- long Abs(long theLong);
-
- OSErr SetUpFlames(CTabHandle flamePalette, CTabHandle destPalette,
- Rect *bounds, char speed, FlamePtr *theFlame)
- {
- short i,
- j,
- closest;
- long tempRed,
- tempGreen,
- tempBlue,
- currentTotal,
- closestTotal;
- Rect tempRect;
- long height, width;
-
- *theFlame = (FlamePtr) NewPtr(sizeof(Flame) + sizeof(IndexNum) * ((*flamePalette)->ctSize));
- tempRect = *bounds;
- tempRect.right = tempRect.right - tempRect.left;
- tempRect.bottom = tempRect.bottom - tempRect.top;
- tempRect.left = tempRect.top = 0;
-
- height = (*flamePalette)->ctSize / 4;
- if (height < tempRect.bottom || speed % 2 == 1)
- height = tempRect.bottom;
- width = tempRect.right;
-
- if (speed == lowRes2)
- {
- width = (width + 1) >> 1;
- height = (height + 1) >> 1;
- }
-
- if (speed == lowRes4)
- {
- width = (width + 1) >> 2;
- height = (height + 1) >> 2;
- }
-
- (**theFlame).speedUp = speed;
- (**theFlame).baseAddr = NewPtrClear(width * (height + 3));
- if ((**theFlame).baseAddr == nil)
- {
- return MemError();
- }
-
- tempRect.right = width;
- tempRect.bottom = height;
- (**theFlame).bounds = tempRect;
- (**theFlame).topLine = tempRect.bottom + 1;
- (**theFlame).rowBytes = tempRect.right;
- (**theFlame).fColSize = (*flamePalette)->ctSize;
- for (i = 0; i < (**theFlame).fColSize; i++)
- {
- for(j = 0; j < (**destPalette).ctSize; j++)
- {
- tempRed = (**destPalette).ctTable[j].rgb.red - (**flamePalette).ctTable[i].rgb.red;
- tempGreen = (**destPalette).ctTable[j].rgb.green - (**flamePalette).ctTable[i].rgb.green;
- tempBlue = (**destPalette).ctTable[j].rgb.blue - (**flamePalette).ctTable[i].rgb.blue;
- currentTotal = Abs(tempRed) + Abs(tempGreen) + Abs(tempBlue);
- if (j == 0 || currentTotal < closestTotal)
- {
- closestTotal = currentTotal;
- closest = j;
- }
- }
- (**theFlame).flameColors[i].ctabNum = closest;
- }
- return noErr;
- }
-
- void KillFlames(FlamePtr *theFlame)
- {
- if (*theFlame != nil)
- {
- DisposePtr((Ptr)(*theFlame)->baseAddr);
- }
- }
-
- void Spark(short x, short y, unsigned char heat, FlamePtr theFlame)
- {
- unsigned char *currentPtr;
-
- if (x > theFlame->bounds.left && x < theFlame->bounds.right &&
- y > theFlame->bounds.top && y < theFlame->bounds.bottom)
- {
- if(y < theFlame->topLine) theFlame->topLine = y;
- currentPtr = (unsigned char *)(theFlame->baseAddr +
- (((long)theFlame->bounds.top + y) * (long)theFlame->rowBytes)) + x;
- *currentPtr = heat;
- }
- }
-
-
- void ChuckInFire(short x, short y, PixMapPtr victim, FlamePtr theFlame)
- {
- short curX, curY, endX, endY, tempY, tempX;
- long total;
- unsigned char colVal[maxColors],
- i, ave;
- unsigned char *srcPtr,
- *destPtr;
-
- short srcRowBytes, destRowBytes;
-
-
- i = 0;
- if (victim->pixelSize != 8) //I don't do thousands of colors
- return;
-
-
- curY = 0;
- theFlame->topLine = y;
- srcRowBytes = victim->rowBytes & 0x3FFF;
- destRowBytes = theFlame->rowBytes;
- do{
- srcPtr = (unsigned char *)victim->baseAddr + ((long)srcRowBytes * (long)curY);
- destPtr = (unsigned char *)theFlame->baseAddr + ((long)destRowBytes * ((long)curY + y)) + x;
- curX = 0;
- do{
- *destPtr = *srcPtr + *destPtr;
- destPtr++;
- srcPtr++;
- curX++;
- } while (curX < victim->bounds.right && curX + x < theFlame->bounds.right);
- curY++;
- }while (curY < victim->bounds.bottom && curX + x < theFlame->bounds.bottom);
- }
-
-
- void SetUpBurn(unsigned char odds, unsigned char max, unsigned char min, FlamePtr theFlame)
- {
- long x = theFlame->bounds.left + 1,
- tempX,
- lenght;
- unsigned char *currentPtr,
- *tempPtr2,
- *tempPtr3,
- randVal = max - min;
-
-
- currentPtr = (unsigned char *)(theFlame->baseAddr +
- (((long)theFlame->bounds.bottom) * (long)theFlame->rowBytes));
- tempPtr2 = (unsigned char *)(theFlame->baseAddr +
- (((long)theFlame->bounds.bottom + 1) * (long)theFlame->rowBytes));
- tempPtr3 = (unsigned char *)(theFlame->baseAddr +
- (((long)theFlame->bounds.bottom + 2) * (long)theFlame->rowBytes));
-
- do{
- if (odds > Rand(255))
- {
- tempX = 0;
- lenght = Rand(randVal);
- lenght += min;
- do{
- *currentPtr = theFlame->fColSize;
- *tempPtr2 = theFlame->fColSize;
- *tempPtr3 = theFlame->fColSize;
- tempX++;
- x++;
- currentPtr++;
- tempPtr2++;
- tempPtr3++;
- }while(tempX < lenght && x < theFlame->bounds.right - 1);
- } else {
- tempX = 0;
- lenght = Rand(max);
- do{
- *currentPtr = 0;
- *tempPtr2 = 0;
- *tempPtr3 = 0;
- tempX++;
- x++;
- currentPtr++;
- tempPtr2++;
- tempPtr3++;
- }while(tempX < lenght && x < theFlame->bounds.right - 1);
- }
- }while (x < theFlame->bounds.right);
- }
-
-
- void Burn (FlamePtr theFlame, unsigned char takeOff, Boolean fuzz)
- {
- long x,y;
- unsigned char *currentPtr,
- *destPtr;
- unsigned char temp1,
- temp2,
- temp3,
- temp4,
- temp5;
- short res,
- lastLine;
- long top;
- unsigned char rArray[100],
- i;
- Boolean fireOnLine = false;
-
- if (fuzz)
- for (i = 0; i < 100; i++) rArray[ i] = Rand(takeOff);
-
- y = theFlame->bounds.bottom + 2;
- do {
- currentPtr = (unsigned char *)(theFlame->baseAddr + ((long)y * (long)theFlame->rowBytes) +
- theFlame->bounds.left + 1);
- destPtr = (unsigned char *) (currentPtr - ((long)theFlame->rowBytes * 2));
- fireOnLine = false;
- for(x = theFlame->bounds.left + 1 ; x < theFlame->bounds.right - 1; x++)
- {
- temp1 = (*(currentPtr));
- temp2 = (*(currentPtr - 1L));
- temp3 = (*(currentPtr + 1L));
- temp4 = (*(currentPtr - (long)theFlame->rowBytes));
- temp5 = *destPtr;
- res = (temp1 + temp2 + temp3 + temp4) >> 2;
- res += *destPtr;
- if (fuzz)
- {
- res -= rArray[i];
- i++;
- if (i == 100) i = 0;
- } else
- res -= takeOff;
- res = res >> 1;
- if (res > theFlame->fColSize)
- res = theFlame->fColSize - 1;
- if (res < 0)
- res = 0;
- if (res > 0)
- fireOnLine = true;
- *destPtr = res;
- destPtr++;
- currentPtr++;
- }
- if (fireOnLine)
- {
- lastLine = y;
- if (y == theFlame->topLine) theFlame->topLine--;
- }
- y--;
- }while(y > theFlame->bounds.top + 2 && y >= theFlame->topLine);
- if (lastLine < theFlame->topLine) theFlame->topLine = lastLine;
- }
-
-
- short Rand(short max)
- {
- return (Random() & 0x7fff) % max;
- }
-
- long Abs(long theLong)
- {
- if (theLong < 0)
- {
- return -theLong;
- } else {
- return theLong;
- }
- }
-
- void CopyFlame(short x, short y, FlamePtr theFlame, PixMapPtr dest)
- {
- short rowBytes;
- long curX,curY;
- unsigned char *srcPtr,
- *destPtr,
- *destPtr2,
- *destPtr3,
- *destPtr4;
-
-
- rowBytes = dest->rowBytes & 0x3FFF;
- if (theFlame->speedUp == noSpeedUp)
- {
- curY = theFlame->bounds.top;
- do {
- destPtr =(unsigned char *) dest->baseAddr + ((long)(y + curY) * (long)rowBytes) +
- (long)dest->bounds.left + x;
- srcPtr = (unsigned char *) theFlame->baseAddr + (theFlame->rowBytes * (long)curY);
- curX = theFlame->bounds.left;
- do{
- *destPtr = theFlame->flameColors[*srcPtr].ctabNum;
- destPtr++;
- srcPtr++;
- curX++;
- } while (curX < theFlame->bounds.right && curX + x < dest->bounds.right);
- curY++;
- }while (curY < theFlame->bounds.bottom && curY + y < dest->bounds.bottom);
- }
- if (theFlame->speedUp == lowRes2)
- {
- curY = theFlame->bounds.top;
- do {
- destPtr = (unsigned char *)dest->baseAddr + (((long)(y + curY) * 2) * (long)rowBytes) +
- (long)dest->bounds.left + x ;
- destPtr2 = (unsigned char *)dest->baseAddr + ( ((long)(y + curY) * 2 + 1) *(long)rowBytes) +
- (long)dest->bounds.left + x;
- srcPtr = (unsigned char *)theFlame->baseAddr + (theFlame->rowBytes * (long)curY);
- curX = theFlame->bounds.left;
- do{
- *destPtr = theFlame->flameColors[*srcPtr].ctabNum;
- *destPtr2 = theFlame->flameColors[*srcPtr].ctabNum;
- destPtr++;
- destPtr2++;
- *destPtr = theFlame->flameColors[*srcPtr].ctabNum;
- *destPtr2 = theFlame->flameColors[*srcPtr].ctabNum;
- destPtr++;
- destPtr2++;
- srcPtr++;
- curX++;
- }while (curX < theFlame->bounds.right && curX + x < dest->bounds.right);
- curY++;
- }while (curY < theFlame->bounds.bottom && curY + y < dest->bounds.bottom);
- }
-
- if (theFlame->speedUp == lowRes4)
- {
- curY = theFlame->bounds.top;
- do {
- destPtr = (unsigned char *)dest->baseAddr + (((long)(y + curY) * 4) *(long)rowBytes) +
- (long)dest->bounds.left + x;
- destPtr2 = (unsigned char *)dest->baseAddr + ( ((long)(y + curY) * 4 + 1) *(long)rowBytes) +
- (long)dest->bounds.left + x;
- destPtr3 = (unsigned char *)dest->baseAddr + (((long)(y + curY) * 4 + 2) *(long)rowBytes) +
- (long)dest->bounds.left + x;
- destPtr4 = (unsigned char *)dest->baseAddr + ( ((long)(y + curY) * 4 + 3) *(long)rowBytes) +
- (long)dest->bounds.left + x;
- srcPtr = (unsigned char *)theFlame->baseAddr + (theFlame->rowBytes * (long)curY);
- curX = theFlame->bounds.left;
- do{
- *destPtr = theFlame->flameColors[*srcPtr].ctabNum;
- *destPtr2 = theFlame->flameColors[*srcPtr].ctabNum;
- *destPtr3 = theFlame->flameColors[*srcPtr].ctabNum;
- *destPtr4 = theFlame->flameColors[*srcPtr].ctabNum;
- destPtr++;
- destPtr2++;
- destPtr3++;
- destPtr4++;
- *destPtr = theFlame->flameColors[*srcPtr].ctabNum;
- *destPtr2 = theFlame->flameColors[*srcPtr].ctabNum;
- *destPtr3 = theFlame->flameColors[*srcPtr].ctabNum;
- *destPtr4 = theFlame->flameColors[*srcPtr].ctabNum;
- destPtr++;
- destPtr2++;
- destPtr3++;
- destPtr4++;
- *destPtr = theFlame->flameColors[*srcPtr].ctabNum;
- *destPtr2 = theFlame->flameColors[*srcPtr].ctabNum;
- *destPtr3 = theFlame->flameColors[*srcPtr].ctabNum;
- *destPtr4 = theFlame->flameColors[*srcPtr].ctabNum;
- destPtr++;
- destPtr2++;
- destPtr3++;
- destPtr4++;
- *destPtr = theFlame->flameColors[*srcPtr].ctabNum;
- *destPtr2 = theFlame->flameColors[*srcPtr].ctabNum;
- *destPtr3 = theFlame->flameColors[*srcPtr].ctabNum;
- *destPtr4 = theFlame->flameColors[*srcPtr].ctabNum;
- destPtr++;
- destPtr2++;
- destPtr3++;
- destPtr4++;
- srcPtr++;
- curX++;
- } while (curX < theFlame->bounds.right && curX + x < dest->bounds.right);
- curY++;
- }while (curY < theFlame->bounds.bottom && curY + y < dest->bounds.bottom);
- }
-
- }
-
- void MaskFlame(short x, short y, FlamePtr theFlame, PixMapPtr dest)
- {
- short rowBytes;
- long curX,curY;
- unsigned char *destPtr,
- *srcPtr,
- *destPtr2,
- *destPtr3,
- *destPtr4;
-
- rowBytes = dest->rowBytes & 0x3FFF;
- if (theFlame->speedUp == noSpeedUp)
- {
- curY = theFlame->bounds.top;
- do {
- destPtr = (unsigned char *)dest->baseAddr + ((long)(y + curY) * (long)rowBytes) +
- (long)dest->bounds.left + x;
- srcPtr = (unsigned char *)theFlame->baseAddr + (theFlame->rowBytes * (long)curY);
- curX = theFlame->bounds.left;
- do{
- if (*srcPtr != 0)
- *destPtr = theFlame->flameColors[*srcPtr].ctabNum;
- destPtr++;
- srcPtr++;
- curX++;
- } while (curX < theFlame->bounds.right && curX + x < dest->bounds.right);
- curY++;
- }while (curY < theFlame->bounds.bottom && curY + y < dest->bounds.bottom);
- }
- if (theFlame->speedUp == lowRes2)
- {
- curY = theFlame->bounds.top;
- do {
- destPtr = (unsigned char *)dest->baseAddr + (((long)(curY + y) * 2) *(long)rowBytes) +
- (long)dest->bounds.left + x;
- destPtr2 = (unsigned char *)dest->baseAddr + ( ((long)(curY + y) * 2 + 1) *(long)rowBytes) +
- (long)dest->bounds.left + x;
- srcPtr =(unsigned char *) theFlame->baseAddr + (theFlame->rowBytes * (long)curY);
- curX = theFlame->bounds.left;
- do{
- if (*srcPtr != 0)
- {
- *destPtr = theFlame->flameColors[*srcPtr].ctabNum;
- *destPtr2 = theFlame->flameColors[*srcPtr].ctabNum;
- }
- destPtr++;
- destPtr2++;
- if (*srcPtr != 0)
- {
- *destPtr = theFlame->flameColors[*srcPtr].ctabNum;
- *destPtr2 = theFlame->flameColors[*srcPtr].ctabNum;
- }
- destPtr++;
- destPtr2++;
- srcPtr++;
- curX++;
- } while (curX < theFlame->bounds.right && curX + x < dest->bounds.right);
- curY++;
- }while (curY < theFlame->bounds.bottom && curY + y < dest->bounds.bottom);
- }
-
- if (theFlame->speedUp == lowRes4)
- {
- curY = theFlame->bounds.top;
- do {
- destPtr = (unsigned char *)dest->baseAddr + (((long)(curY + y) * 4) *(long)rowBytes) +
- (long)dest->bounds.left + x;
- destPtr2 = (unsigned char *)dest->baseAddr + ( ((long)(curY + y) * 4 + 1) *(long)rowBytes) +
- (long)dest->bounds.left + x;
- destPtr3 = (unsigned char *)dest->baseAddr + (((long)(curY + y) * 4 + 2) *(long)rowBytes) +
- (long)dest->bounds.left + x;
- destPtr4 = (unsigned char *)dest->baseAddr + ( ((long)(curY + y) * 4 + 3) *(long)rowBytes) +
- (long)dest->bounds.left + x;
- srcPtr = (unsigned char *)theFlame->baseAddr + (theFlame->rowBytes * (long)curY);
- curX = theFlame->bounds.left;
- do{
- if (*srcPtr != 0)
- {
- *destPtr = theFlame->flameColors[*srcPtr].ctabNum;
- *destPtr2 = theFlame->flameColors[*srcPtr].ctabNum;
- *destPtr3 = theFlame->flameColors[*srcPtr].ctabNum;
- *destPtr4 = theFlame->flameColors[*srcPtr].ctabNum;
- }
- destPtr++;
- destPtr2++;
- destPtr3++;
- destPtr4++;
- if (*srcPtr != 0)
- {
- *destPtr = theFlame->flameColors[*srcPtr].ctabNum;
- *destPtr2 = theFlame->flameColors[*srcPtr].ctabNum;
- *destPtr3 = theFlame->flameColors[*srcPtr].ctabNum;
- *destPtr4 = theFlame->flameColors[*srcPtr].ctabNum;
- }
- destPtr++;
- destPtr2++;
- destPtr3++;
- destPtr4++;
- if (*srcPtr != 0)
- {
- *destPtr = theFlame->flameColors[*srcPtr].ctabNum;
- *destPtr2 = theFlame->flameColors[*srcPtr].ctabNum;
- *destPtr3 = theFlame->flameColors[*srcPtr].ctabNum;
- *destPtr4 = theFlame->flameColors[*srcPtr].ctabNum;
- }
- destPtr++;
- destPtr2++;
- destPtr3++;
- destPtr4++;
- if (*srcPtr != 0)
- {
- *destPtr = theFlame->flameColors[*srcPtr].ctabNum;
- *destPtr2 = theFlame->flameColors[*srcPtr].ctabNum;
- *destPtr3 = theFlame->flameColors[*srcPtr].ctabNum;
- *destPtr4 = theFlame->flameColors[*srcPtr].ctabNum;
- }
- destPtr++;
- destPtr2++;
- destPtr3++;
- destPtr4++;
- srcPtr++;
- curX++;
- } while (curX < theFlame->bounds.right && curX + x < dest->bounds.right);
- curY++;
- }while (curY < theFlame->bounds.bottom && curY + y < dest->bounds.bottom);
- }
- }
-